Day2 정답률 높은 문제 2
✒️ 2024-03-23 17:40 내용 수정
Day2 2단계 20240323
1. x만큼 감격이 있는 n개의 숫자
- 내 풀이 : answer 배열의 크기는 n과 같고, 배열의 각 요소는 x를 (index+1)와 곱한 것과 동일하다.
- 여기서 x는 int로 주어졌기 때문에 만약
x = -10000000또는x = 10000000이고,n = 1000일 때 배열의 마지막 요소를 long으로 변환하지 않으면 int overflow가 발생한다. 따라서 x를 long으로 변환한 후 연산을 진행했다.
class Solution {
public long[] solution(int x, int n) {
long[] answer = new long[n];
for(int i = 0; i < n; i++) {
answer[i] = (long)x*(i+1);
}
return answer;
}
}
x = -10000000,n = 1000일 때answer[i] = x*(i+1)을 연산하면 아래 사진과 같이 overflow가 발생한다.
2. 자연수 뒤집어 배열로 만들기
- 내 풀이 : 먼저 결과 배열의 크기를 구하기 위해 자연수 n을
String.valueOf(n).length()로 String 변환 후 String의 길이를 얻는 방법으로 자릿수를 구했다. - 배열의 크기를 구해 answer의 크기를 먼저 초기화해준다.
- 각 자리 숫자를 원소로 가지기 때문에 먼저 answer의 첫 요소인 일의 자리 숫자는 자연수 n을 10으로 나눈 나머지로 얻을 수 있으며, n을 10으로 나눈 몫을 다음 루프에서 다시 10으로 나눴을 때 새긴 나머지가 2번째 요소가 된다.
- Day1 정답률 높은 문제 1#4. 자릿수 더하기의 2번 풀이 참고.
class Solution {
public int[] solution(long n) {
int size = String.valueOf(n).length();
int[] answer = new int[size];
for(int i = 0; i < size; i++) {
answer[i] = (int)(n%10);
n /= 10;
}
return answer;
}
}
3. 문자열 내 p와 y의 개수
- 내 풀이 : 문제를 읽었을 때 두 가지 방법을 고민했는데, 첫 번째는 String s의 각 index의 char를 읽어 p와 y의 개수를 각각 count하는 것이고, 두 번째는
String.replace()를 사용하여 p와 y를 공백으로 바꾼 후 원본 String s의 길이와 비교하여 개수를 얻는 방법이다. 첫 번째 방법은 구현을 자주 했던 방법이라서 두 번째 방법을 구현해봤다. - 먼저 문제에서 p와 y가 String s 내에 대소문자로 섞여 있고, 개수를 셀 때 대소문자를 구분하지 않는다고 했으므로
String.toLowerCase()를 사용하여 s를 모두 소문자(혹은 대문자)로 바꿨다. - 그 다음
replace("p", "")로 s 내의 p를 모두 공백으로 바꾼 다음 원본 길이에서 새 길이(numOfP)를 뺀 값을 p의 개수로 저장하고, 원본 길이에서 p의 개수를 뺀 새 길이를 저장했다. replace("y", "")로 s 내의 y를 모두 공백으로 바꾼 다음 마찬가지로 길이값에서 새 길이(numOfY)를 뺀 값을 y의 개수로 저장했다.- 마지막으로 삼항 연산자를 사용하여
numOfP == numOfY라면 true를, 다르다면 false를 반환하며, 이 경우엔 String s내에 p와 y가 둘 다 없을 때numOfP == numOfY == 0이므로 true를 반환한다.
class Solution {
boolean solution(String s) {
s = s.toLowerCase();
int length = s.length();
s = s.replace("p", "");
int numOfP = length - s.length();
length -= numOfP;
s = s.replace("y", "");
int numOfY = length - s.length();
return (numOfP == numOfY) ? true : false;
}
}
- 다른 사람 풀이 : 정규 표현식을 사용하여 p와 P, y와 Y를 공백으로 치환하고, 그 길이를 비교했다.
- 이 방법을 사용한다면 코드가 훨씬 더 간결해진다.
class Solution {
boolean solution(String s) {
int numOfP = s.replaceAll("[^pP]", s).length();
int numOfY = s.replaceAll("[^yY]", s).length();
return (numOfP == numOfY) ? true : false;
}
}
- stream으로 푼 풀이의 댓글 중 stream, for문 count, replaceAll("regex", "")의 속도를 비교한 글이 있는데, 해당 문제와 같은 String s에 대해선 속도는 for문 count, replaceAll("regex", ""), stream 순으로 빠르다는 내용이 있다.
- 이를 직접 비교하기 위해 count를 하는 코드도 작성하여 테스트 속도를 비교했다.
class Solution {
boolean solution(String s) {
int numOfP = 0;
int numOfY = 0;
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) == 'p' || s.charAt(i) == 'P') {
numOfP++;
} else if (s.charAt(i) == 'y' || s.charAt(i) == 'Y') {
numOfY++;
}
}
return (numOfP == numOfY) ? true : false;
}
}
- for문 count 코드의 결과가 replace()를 사용한 코드보다 더 빠른 것을 볼 수 있다.
4. 정수 제곱근 판별
- 내 풀이 : 양의 정수 n을
Math.sqrt(n)로 제곱근을 얻고, 그 결과가 정수라면 (제곱근+1)^2을 반환하고, 아니라면 -1을 삼항 연산자로 반환했다. - 조건에서 n이 50000000000000 이하의 양의 정수라고 나와 있었기에 삼항 연산자로 반환할 결과를 long으로 변환했다.
class Solution {
public long solution(long n) {
double sqt = Math.sqrt(n);
return (sqt == (int)sqt) ? (long)((int)sqt+1)*((int)sqt+1) : -1;
}
}
- 다른 사람 풀이 : 제곱근이 정수인지 판별하는 방법 중
Math.floor()를 사용하여 판별한 방법도 있었다.